package edu.nus.cs4243.recon.logic;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import edu.nus.cs4243.recon.model.Feature;
import edu.nus.cs4243.recon.model.Image;
import edu.nus.cs4243.recon.model.SceneView;
import edu.nus.cs4243.recon.utils.Pair;

/**
 * Class for choosing image pairs for reconstruction using multiple views.
 * 
 * @author Piotr
 */
public class ImageChooser {
	public List<Pair<SceneView, SceneView>> pairs;

	public ImageChooser(List<SceneView> views) {
		double n = getAverageNumberOfCommonFeatures(views);
		pairs = imagesWithCommonFeatures(n, views);
	}

	/**
	 * Returns list of pairs of images with common features
	 * 
	 * @param n
	 *            average number of common features
	 * @param imgList
	 *            list of all images
	 * @return List of images with common features
	 */
	private List<Pair<SceneView, SceneView>> imagesWithCommonFeatures(double n,
			List<SceneView> imgList) {
		List<Pair<SceneView, SceneView>> images = new ArrayList<Pair<SceneView, SceneView>>();

		for (int i = 0; i < imgList.size(); i++) {
			SceneView imgI = imgList.get(i);
			for (int j = 0; j < imgList.size(); j++) {
				if (j > i) {
					SceneView imgJ = imgList.get(j);
					Collection<Feature> f = imgJ.getCommonFeatures(imgI);
					if (f.size() >= n) {
						images.add(new Pair<SceneView, SceneView>(imgI, imgJ));
					}
				}
			}
		}
		return images;
	}

	/**
	 * Computes average number of common features for all images
	 * 
	 * @param imgList
	 *            the list of all images
	 * @return average number of common features
	 */
	private double getAverageNumberOfCommonFeatures(List<SceneView> imgList) {
		int numberOfFeatures = 0;
		for (int i = 0; i < imgList.size(); i++) {
			SceneView imgI = imgList.get(i);
			for (int j = 0; j < imgList.size(); j++) {
				if (j > i) {
					SceneView imgJ = imgList.get(j);
					Collection<Feature> f = imgJ.getCommonFeatures(imgI);
					numberOfFeatures += f.size();
				}
			}
		}
		return numberOfFeatures / (imgList.size() / 2.0 * (imgList.size() - 1));
	}

	/**
	 * Return the selected pairs of images.
	 * 
	 * @return list of pairs of images.
	 */
	public List<Pair<SceneView, SceneView>> getPairs() {
		return pairs;
	}

}
